package cn.yh.nft.turbo.collection.facade;

import cn.yh.nft.turbo.api.chain.constant.ChainOperateBizTypeEnum;
import cn.yh.nft.turbo.api.chain.request.ChainProcessRequest;
import cn.yh.nft.turbo.api.chain.service.ChainFacadeService;
import cn.yh.nft.turbo.api.collection.constant.CollectionInventoryModifyType;
import cn.yh.nft.turbo.api.collection.model.CollectionVO;
import cn.yh.nft.turbo.api.collection.request.*;
import cn.yh.nft.turbo.api.collection.response.CollectionChainResponse;
import cn.yh.nft.turbo.api.collection.response.CollectionInventoryModifyResponse;
import cn.yh.nft.turbo.api.collection.response.CollectionModifyResponse;
import cn.yh.nft.turbo.api.collection.response.CollectionRemoveResponse;
import cn.yh.nft.turbo.api.collection.service.CollectionManageFacadeService;
import cn.yh.nft.turbo.api.collection.service.CollectionReadFacadeService;
import cn.yh.nft.turbo.api.inventory.request.InventoryRequest;
import cn.yh.nft.turbo.api.inventory.service.InventoryFacadeService;
import cn.yh.nft.turbo.api.user.service.UserFacadeService;
import cn.yh.nft.turbo.base.response.PageResponse;
import cn.yh.nft.turbo.base.response.SingleResponse;
import cn.yh.nft.turbo.collection.domain.entity.Collection;
import cn.yh.nft.turbo.collection.domain.entity.convertor.CollectionConvertor;
import cn.yh.nft.turbo.collection.domain.response.CollectionInventoryResponse;
import cn.yh.nft.turbo.collection.domain.service.CollectionInventoryService;
import cn.yh.nft.turbo.collection.domain.service.CollectionService;
import cn.yh.nft.turbo.collection.exception.CollectionException;
import com.alibaba.fastjson2.JSON;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import static cn.yh.nft.turbo.collection.exception.CollectionErrorCode.COLLECTION_INVENTORY_UPDATE_FAILED;

/**
 * <p>
 *     藏品管理服务
 * </p>
 * @ClassName: CollectionManageFacadeServiceImpl
 * @Author: 草莓爱上啵啵
 */
@DubboService(version = "1.0.0")
public class CollectionManageFacadeServiceImpl implements CollectionManageFacadeService {

    private static final Logger logger = LoggerFactory.getLogger(CollectionManageFacadeServiceImpl.class);

    @Autowired
    private ChainFacadeService chainFacadeService;

    @Autowired
    private CollectionService collectionService;

    @Autowired
    private CollectionReadFacadeService collectionReadFacadeService;

    @Autowired
    private InventoryFacadeService inventoryFacadeService;

    @Autowired
    private UserFacadeService userFacadeService;

    /**
     * 创建藏品
     * @param request 创建藏品请求对象
     * @return
     */
    @Override
    public CollectionChainResponse create(CollectionCreateRequest request) {
        //将请求参数对象出传入创建服务层创建藏品/真正的创建逻辑
        Collection collection = collectionService.create(request);

        //因为以上方法中已经判断藏品是否能创建成功了，返回的一定不是空数据，这里就不过多做判断
        //藏品创建成功以后，需要进行上链操作，因为上链操作可以保证该藏品是一个虚拟且真实的藏品
        //在区块链上可以确保唯一性以及稀缺性，能够完全确保，你只要拥有了该藏品就百分百是你的
        ChainProcessRequest chainProcessRequest = new ChainProcessRequest();
        //设置当前唯一幂等号
        chainProcessRequest.setIdentifier(request.getIdentifier());
        //设置类别id
        chainProcessRequest.setClassId(String.valueOf(collection.getId()));
        //设置藏品名称
        chainProcessRequest.setClassName(request.getName());
        //设置藏品操作类型
        chainProcessRequest.setBizType(ChainOperateBizTypeEnum.COLLECTION.name());


        chainProcessRequest.setBizId(collection.getId().toString());
        var chainRes = chainFacadeService.chain(chainProcessRequest);
        CollectionChainResponse response = new CollectionChainResponse();

        //判断是否上链成功
        if (!chainRes.getSuccess()) {
            response.setSuccess(false);
            return response;
        }

        //上链成功
        response.setSuccess(true);
        response.setCollectionId(collection.getId());
        return response;
    }

    /**
     * 下架藏品
     * @param request 下架藏品请求对象
     * @return
     */
    @Override
    public CollectionRemoveResponse remove(CollectionRemoveRequest request) {
        //创建响应对象
        CollectionRemoveResponse response = new CollectionRemoveResponse();
        //调用remove方法下架藏品
        Boolean result = collectionService.remove(request);

        //判断是否下架成功
        if (result) {
            //成功删除redis中缓存的库存
            InventoryRequest inventoryRequest = new InventoryRequest();
            inventoryRequest.setGoodsId(request.getCollectionId().toString());
            //调用invalid方法删除缓存库存
            inventoryFacadeService.invalid(inventoryRequest);
        }

        //将结果设置到响应对象中
        response.setSuccess(result);
        //设置藏品id
        response.setCollectionId(request.getCollectionId());
        //设置成功结果
        return response;
    }

    /**
     * 修改库存，数据库和redis库存进行同步
     * @param request
     * @return
     */
    @Override
    public CollectionModifyResponse modifyInventory(CollectionModifyInventoryRequest request) {

        CollectionModifyResponse response = new CollectionModifyResponse();
        response.setCollectionId(request.getCollectionId());

        CollectionInventoryModifyResponse modifyResponse = collectionService.modifyInventory(request);

        //如果修改库存失败则返回失败结果
        if (!modifyResponse.getSuccess()){
            response.setSuccess(false);
            response.setResponseCode(COLLECTION_INVENTORY_UPDATE_FAILED.getMessage());
            return response;
        }

        //如果修改类型为未修改直接返回修改成功，不做以下操作
        if (modifyResponse.getModifyType() == CollectionInventoryModifyType.UNMODIFIED) {
            response.setSuccess(true);
            return response;
        }

        //构建一个库存请求对象
        InventoryRequest inventoryRequest = new InventoryRequest();
        //设置藏品id
        inventoryRequest.setGoodsId(request.getCollectionId().toString());
        //设置幂等号
        inventoryRequest.setIdentifier(request.getIdentifier());
        //将库存设置为修改后的结果
        inventoryRequest.setInventory(modifyResponse.getQuantityModified().intValue());
        //创建一个库存响应对象
        SingleResponse<Boolean> inventoryResponse;
        //如果是增加调用increase方法
        if (modifyResponse.getModifyType() == CollectionInventoryModifyType.INCREASE) {
            inventoryResponse = inventoryFacadeService.increase(inventoryRequest);
        } else {
            //如果是减少调用decrease方法
            inventoryResponse = inventoryFacadeService.decrease(inventoryRequest);
        }

        //如果失败返回修改失败结果
        if (!inventoryResponse.getSuccess()) {
            logger.error("modify inventory failed : " + JSON.toJSONString(inventoryResponse));
            throw new CollectionException(COLLECTION_INVENTORY_UPDATE_FAILED);
        }

        //返回修改成功
        response.setSuccess(true);
        return response;

    }

    /**
     * 修改价格
     * @param request 修改价格请求对象
     * @return
     */
    @Override
    public CollectionModifyResponse modifyPrice(CollectionModifyPriceRequest request) {
        Boolean result = collectionService.modifyPrice(request);
        CollectionModifyResponse response = new CollectionModifyResponse();
        response.setSuccess(result);
        response.setCollectionId(request.getCollectionId());

        return response;
    }

    /**
     * 分页查询商品列表
     * @param request
     * @return
     */
    @Override
    public PageResponse<CollectionVO> pageQuery(CollectionPageQueryRequest request) {
        PageResponse<Collection> collectionPage = collectionService.pageQueryByState(request.getKeyword(), request.getState(), request.getCurrentPage(), request.getPageSize());
        return PageResponse.of(CollectionConvertor.INSTANCE.mapToVo(collectionPage.getDatas()), collectionPage.getTotal(), collectionPage.getPageSize(), request.getCurrentPage() );
    }



}
